home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D GFX
/
3D GFX.iso
/
amiutils
/
i_l
/
irit5
/
cagd_lib
/
cagdcoer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-30
|
20KB
|
438 lines
/******************************************************************************
* CagdCoer.c - Handle point coercesions/conversions. *
*******************************************************************************
* Written by Gershon Elber, Aug. 90. *
******************************************************************************/
#include "cagd_loc.h"
/*****************************************************************************
* DESCRIPTION: M
* Coerce Srf/Crv Point from index Index of Points array of Type PType to a M
* point type E2. M
* If however Index < 0 Points is considered single point. M
* *
* PARAMETERS: M
* E2Point: Where the coerced information is to besaved. M
* Points: Array of vectors if Index >= 0, a single point if Index < 0. M
* Index: Index into the vectors of Points. M
* PType: Point type to be expected from Points. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* CagdCoerceToE2, coercion M
*****************************************************************************/
void CagdCoerceToE2(CagdRType *E2Point,
CagdRType *Points[CAGD_MAX_PT_SIZE],
int Index,
CagdPointType PType)
{
CagdBType
IsRational = CAGD_IS_RATIONAL_PT(PType);
int i,
MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
CagdRType *Point;
if (MaxCoord > 2)
MaxCoord = 2;
if (Index < 0) { /* Points is one single point. */
Point = *Points;
for (i = 1; i <= MaxCoord; i++)
*E2Point++ = IsRational ? Point[i] / Point[W] : Point[i];
}
else /* Points is a full arrays from Srf or Crv. */
for (i = 1; i <= MaxCoord; i++)
*E2Point++ = IsRational ? Points[i][Index] / Points[W][Index] :
Points[i][Index];
for (i = MaxCoord + 1; i <= 2; i++)
*E2Point++ = 0.0;
}
/*****************************************************************************
* DESCRIPTION: M
* Coerce Srf/Crv Point from index Index of Points array of Type PType to a M
* point type E3. M
* If however Index < 0 Points is considered single point. M
* *
* PARAMETERS: M
* E3Point: Where the coerced information is to besaved. M
* Points: Array of vectors if Index >= 0, a single point if Index < 0. M
* Index: Index into the vectors of Points. M
* PType: Point type to be expected from Points. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* CagdCoerceToE3 coercion M
*****************************************************************************/
void CagdCoerceToE3(CagdRType *E3Point,
CagdRType *Points[CAGD_MAX_PT_SIZE],
int Index,
CagdPointType PType)
{
CagdBType
IsRational = CAGD_IS_RATIONAL_PT(PType);
int i,
MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
CagdRType *Point;
if (MaxCoord > 3)
MaxCoord = 3;
if (Index < 0) { /* Points is one single point. */
Point = *Points;
for (i = 1; i <= MaxCoord; i++)
*E3Point++ = IsRational ? Point[i] / Point[W] : Point[i];
}
else /* Points is a full arrays from Srf or Crv. */
for (i = 1; i <= MaxCoord; i++)
*E3Point++ = IsRational ? Points[i][Index] / Points[W][Index] :
Points[i][Index];
for (i = MaxCoord + 1; i <= 3; i++)
*E3Point++ = 0.0;
}
/*****************************************************************************
* DESCRIPTION: M
* Coerce Srf/Crv Point from index Index of Points array of Type PType to a M
* point type P2. M
* If however Index < 0 Points is considered single point. M
* *
* PARAMETERS: M
* P2Point: Where the coerced information is to besaved. M
* Points: Array of vectors if Index >= 0, a single point if Index < 0. M
* Index: Index into the vectors of Points. M
* PType: Point type to be expected from Points. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* CagdCoerceToP2, coercion M
*****************************************************************************/
void CagdCoerceToP2(CagdRType *P2Point,
CagdRType *Points[CAGD_MAX_PT_SIZE],
int Index,
CagdPointType PType)
{
CagdBType
IsRational = CAGD_IS_RATIONAL_PT(PType);
int i,
MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
CagdRType *Point;
if (MaxCoord > 2)
MaxCoord = 2;
if (Index < 0) { /* Points is one single point. */
Point = *Points;
*P2Point++ = IsRational ? Point[W] : 1.0;
for (i = 1; i <= MaxCoord; i++)
*P2Point++ = Point[i];
}
else { /* Points is a full arrays from Srf or Crv. */
*P2Point++ = IsRational ? Points[W][Index] : 1.0;
for (i = 1; i <= MaxCoord; i++)
*P2Point++ = Points[i][Index];
}
for (i = MaxCoord + 1; i <= 2; i++)
*P2Point++ = 0.0;
}
/*****************************************************************************
* DESCRIPTION: M
* Coerce Srf/Crv Point from index Index of Points array of Type PType to a M
* point type P3. M
* If however Index < 0 Points is considered single point. M
* *
* PARAMETERS: M
* P3Point: Where the coerced information is to besaved. M
* Points: Array of vectors if Index >= 0, a single point if Index < 0. M
* Index: Index into the vectors of Points. M
* PType: Point type to be expected from Points. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* CagdCoerceToP3, coercion M
*****************************************************************************/
void CagdCoerceToP3(CagdRType *P3Point,
CagdRType *Points[CAGD_MAX_PT_SIZE],
int Index,
CagdPointType PType)
{
CagdBType
IsRational = CAGD_IS_RATIONAL_PT(PType);
int i,
MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
CagdRType *Point;
if (MaxCoord > 3)
MaxCoord = 3;
if (Index < 0) { /* Points is one single point. */
Point = *Points;
*P3Point++ = IsRational ? Point[W] : 1.0;
for (i = 1; i <= MaxCoord; i++)
*P3Point++ = Point[i];
}
else { /* Points is a full arrays from Srf or Crv. */
*P3Point++ = IsRational ? Points[W][Index] : 1.0;
for (i = 1; i <= MaxCoord; i++)
*P3Point++ = Points[i][Index];
}
for (i = MaxCoord + 1; i <= 3; i++)
*P3Point++ = 0.0;
}
/*****************************************************************************
* DESCRIPTION: M
* Coerces Srf/Crv Point from index Index of Points array of Type PType to a M
* new type NewPType. If however Index < 0 Points is considered single point. M
* *
* PARAMETERS: M
* NewPoint: Where the coerced information is to besaved. M
* NewPType: Point type of the coerced new point. M
* Points: Array of vectors if Index >= 0, a single point if Index < 0. M
* Index: Index into the vectors of Points. M
* OldPType: Point type to be expected from Points. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* CagdCoercePointTo, coercion M
*****************************************************************************/
void CagdCoercePointTo(CagdRType *NewPoint,
CagdPointType NewPType,
CagdRType *Points[CAGD_MAX_PT_SIZE],
int Index,
CagdPointType OldPType)
{
CagdBType
IsRational = CAGD_IS_RATIONAL_PT(OldPType),
NewIsRational = CAGD_IS_RATIONAL_PT(NewPType);
int i,
MaxCoord = CAGD_NUM_OF_PT_COORD(OldPType),
NewMaxCoord = CAGD_NUM_OF_PT_COORD(NewPType);
CagdRType *Point, Weight;
if (MaxCoord > NewMaxCoord)
MaxCoord = NewMaxCoord;
if (Index < 0) { /* Points is one single point. */
Point = *Points;
Weight = IsRational ? Point[W] : 1.0;
if (NewIsRational) {
*NewPoint++ = Weight;
Weight = 1.0;
}
for (i = 1; i <= MaxCoord; i++)
*NewPoint++ = Point[i] / Weight;
}
else { /* Points is a full arrays from Srf or Crv. */
Weight = IsRational ? Points[W][Index] : 1.0;
if (NewIsRational) {
*NewPoint++ = Weight;
Weight = 1.0;
}
for (i = 1; i <= MaxCoord; i++)
*NewPoint++ = Points[i][Index] / Weight;
}
for (i = MaxCoord + 1; i <= NewMaxCoord; i++)
*NewPoint++ = 0.0;
}
/*****************************************************************************
* DESCRIPTION: M
* Coerces an array of vectors, Points. of point type OldPType to point type M
* NewPType, in place. M
* *
* PARAMETERS: M
* Points: Where the old and new points are placed. M
* Len: Length of vectors in the array of vectors, Points. M
* OldPType: Point type to be expected from Points. M
* NewPType: Point type of the coerced new point. M
* *
* RETURN VALUE: M
* void M
* M
* KEYWORDS: M
* CagdCoercePointsTo, coercion M
*****************************************************************************/
void CagdCoercePointsTo(CagdRType *Points[],
int Len,
CagdPointType OldPType,
CagdPointType NewPType)
{
int i, j,
OldIsRational = CAGD_IS_RATIONAL_PT(OldPType),
OldNumOfCoords = CAGD_NUM_OF_PT_COORD(OldPType),
NewIsRational = CAGD_IS_RATIONAL_PT(NewPType),
NewNumOfCoords = CAGD_NUM_OF_PT_COORD(NewPType);
CagdRType *NewPoints[CAGD_MAX_PT_SIZE], Pt[CAGD_MAX_PT_SIZE];
for (i = !NewIsRational; i <= NewNumOfCoords; i++)
NewPoints[i] = (CagdRType *) IritMalloc(sizeof(CagdRType) * Len);
for (i = 0; i < Len; i++) {
CagdCoercePointTo(Pt, NewPType, Points, i, OldPType);
if (NewIsRational)
for (j = 0; j <= NewNumOfCoords; j++)
NewPoints[j][i] = Pt[j];
else
for (j = 1; j <= NewNumOfCoords; j++)
NewPoints[j][i] = Pt[j - 1];
}
/* Replace old rep. with new. */
for (i = !OldIsRational; i <= OldNumOfCoords; i++)
IritFree((VoidPtr) Points[i]);
Points[0] = NULL;
for (i = !NewIsRational; i <= NewNumOfCoords; i++)
Points[i] = NewPoints[i];
for (; i <= CAGD_MAX_PT_COORD; i++)
Points[i] = NULL;
}
/*****************************************************************************
* DESCRIPTION: M
* Coerces a curve to a new point type PType. If given curve is E1 or P1 M
* and requested new type is E2 or P2 the Y coefficients are updated to M
* hold the parametric domain of the curve. M
* *
* PARAMETERS: M
* Crv: To be coerced to a new point type PType. M
* PType: New point type for Crv. M
* *
* RETURN VALUE: M
* CagdCrvStruct *: The new, coerced to PType, curve. M
* *
* KEYWORDS: M
* CagdCoerceCrvTo, coercion M
*****************************************************************************/
CagdCrvStruct *CagdCoerceCrvTo(CagdCrvStruct *Crv, CagdPointType PType)
{
Crv = CagdCrvCopy(Crv);
CagdCoercePointsTo(Crv -> Points, Crv -> Length, Crv -> PType, PType);
if (CAGD_NUM_OF_PT_COORD(Crv -> PType) == 1 &&
CAGD_NUM_OF_PT_COORD(PType) == 2) {
/* Update the parameter space to be the second axis. */
CagdRType
*WPts = Crv -> Points[0],
*Pts = Crv -> Points[2],
*Nodes = CagdCrvNodes(Crv);
CAGD_GEN_COPY(Pts, Nodes, sizeof(CagdRType) * Crv -> Length);
if (WPts != NULL) {
int i;
for (i = 0; i < Crv -> Length; i++)
*Pts++ *= *WPts++;
}
IritFree((VoidPtr) Nodes);
}
Crv -> PType = PType;
return Crv;
}
/*****************************************************************************
* DESCRIPTION: M
* Coerces a surface to a new point type PType. If given surface is E1 or P1 M
* and requested new type is E3 or P3 the Y and Z coefficients are updated to M
* hold the parametric domain of the surface. M
* *
* PARAMETERS: M
* Srf: To be coerced to a new point type PType. M
* PType: New point type for Srf. M
* *
* RETURN VALUE: M
* CagdSrfStruct *: The new, coerced to PType, surface. M
* *
* KEYWORDS: M
* CagdCoerceSrfTo, coercion M
*****************************************************************************/
CagdSrfStruct *CagdCoerceSrfTo(CagdSrfStruct *Srf, CagdPointType PType)
{
Srf = CagdSrfCopy(Srf);
CagdCoercePointsTo(Srf -> Points, Srf -> ULength * Srf -> VLength,
Srf -> PType, PType);
if (CAGD_NUM_OF_PT_COORD(Srf -> PType) == 1 &&
CAGD_NUM_OF_PT_COORD(PType) == 3) {
/* Update the parameter space to be the second and third axis. */
int i;
CagdRType *PtsY, *PtsZ,
*WPts = Srf -> Points[0],
*UNodes = CagdSrfNodes(Srf, CAGD_CONST_U_DIR),
*VNodes = CagdSrfNodes(Srf, CAGD_CONST_V_DIR);
for (i = 0, PtsY = Srf -> Points[2];
i < Srf -> VLength;
i++, PtsY += Srf -> ULength)
CAGD_GEN_COPY(PtsY, UNodes, sizeof(CagdRType) * Srf -> ULength);
for (i = 0, PtsZ = Srf -> Points[3]; i < Srf -> VLength; i++) {
int j;
for (j = 0; j < Srf -> ULength; j++)
*PtsZ++ = VNodes[i];
}
if (WPts != NULL) {
PtsY = Srf -> Points[2];
PtsZ = Srf -> Points[3];
for (i = 0; i < Srf -> ULength * Srf -> VLength; i++) {
*PtsY++ *= *WPts;
*PtsZ++ *= *WPts++;
}
}
IritFree((VoidPtr) UNodes);
IritFree((VoidPtr) VNodes);
}
Srf -> PType = PType;
return Srf;
}
/*****************************************************************************
* DESCRIPTION: M
* Returns a point type which spans the spaces of both two given point types. M
* *
* PARAMETERS: M
* PType1, PType2: To point types to find the point type of their union. M
* *
* RETURN VALUE: M
* CagdPointType: A point type of the union of the spaces of PType1 and M
* PType2. M
* *
* KEYWORDS: M
* CagdMergePointType, coercion M
*****************************************************************************/
CagdPointType CagdMergePointType(CagdPointType PType1, CagdPointType PType2)
{
CagdBType
IsRational = CAGD_IS_RATIONAL_PT(PType1) || CAGD_IS_RATIONAL_PT(PType2);
int NumCoords = MAX(CAGD_NUM_OF_PT_COORD(PType1),
CAGD_NUM_OF_PT_COORD(PType2));
return CAGD_MAKE_PT_TYPE(IsRational, NumCoords);
}